package com.ruoyi.supply.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import java.util.*;
import java.util.stream.Collectors;

import com.ruoyi.common.constant.CacheConstants;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.framework.web.service.TokenService;
import com.ruoyi.supply.enums.MemberGradeEnum;
import com.ruoyi.system.domain.SysUserOnline;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.supply.mapper.TMemberMapper;
import com.ruoyi.supply.domain.TMember;
import org.springframework.transaction.annotation.Transactional;

/**
 * 会员管理Service业务层处理
 * 
 * @author Ryan
 * @date 2025-06-13
 */
@Service
@Slf4j
public class TMemberService extends ServiceImpl<TMemberMapper, TMember>
{
    @Autowired
    private TMemberMapper tMemberMapper;


    @Autowired
    private RedisCache redisCache;

    @Autowired
    private TokenService tokenService;
    /**
     * 查询会员管理
     * 
     * @param id 会员管理主键
     * @return 会员管理
     */
    public TMember selectTMemberById(Long id)
    {
        return tMemberMapper.selectTMemberById(id);
    }

    /**
     * 查询会员管理列表
     * 
     * @param tMember 会员管理
     * @return 会员管理
     */
    public List<TMember> selectTMemberList(TMember tMember)
    {
        return tMemberMapper.selectTMemberList(tMember);
    }

    /**
     * 新增会员管理
     * 
     * @param tMember 会员管理
     * @return 结果
     */
    public int insertTMember(TMember tMember)
    {
        tMember.setCreateTime(DateUtils.getNowDate());
        return baseMapper.insert(tMember);
    }

    /**
     * 修改会员管理
     * 
     * @param tMember 会员管理
     * @return 结果
     */
    public int updateTMember(TMember tMember)
    {
        tMember.setGrade(null);
        tMember.setStatus(null);
        tMember.setUpdateTime(DateUtils.getNowDate());
        return baseMapper.updateById(tMember);
    }

    public void updateStatus(Long id, String status){
        lambdaUpdate().set(TMember::getStatus, status).eq(TMember::getId, id).update();
    }

    public void updateGrade(Long id,String grade){
        lambdaUpdate().set(TMember::getGrade, grade).eq(TMember::getId, id);
    }



    /**
     * 批量删除会员管理
     * 
     * @param ids 需要删除的会员管理主键
     * @return 结果
     */
    public int deleteTMemberByIds(Long[] ids)
    {
        return tMemberMapper.deleteBatchIds(Arrays.asList(ids));
    }

    /**
     * 删除会员管理信息
     * 
     * @param id 会员管理主键
     * @return 结果
     */
    public int deleteTMemberById(Long id)
    {
        return tMemberMapper.deleteById(id);
    }

    public Optional<TMember> findByOpenId(String openid) {
       return lambdaQuery().eq(TMember::getOpenid, openid).orderByDesc(TMember::getCreateTime).last("limit 1").oneOpt();
    }

    @Transactional(rollbackFor = Exception.class)
    public TMember plusMemberTime(Long memberId, MemberGradeEnum gradeEnum){
        TMember tMember = getById(memberId);
        if(Objects.isNull(tMember.getActivationTime())){
            tMember.setActivationTime(new Date());
            tMember.setExpirationTime(DateUtils.addMonths(tMember.getActivationTime(), gradeEnum.getMonth()));
            log.info("用户:{},购买会员:{}，最新的过期时间为:{}", memberId, gradeEnum.getDesc(), tMember.genExpirationTimeStr());
        }else{
            tMember.setExpirationTime(DateUtils.addMonths(tMember.getExpirationTime(), gradeEnum.getMonth()));
            log.info("用户:{},增加会员:{}，最新的过期时间为:{}", memberId, gradeEnum.getDesc(), tMember.genExpirationTimeStr());
        }
        TMember updateData = new TMember();
        updateData.setId(tMember.getId());
        updateData.setActivationTime(tMember.getActivationTime());
        updateData.setExpirationTime(tMember.getExpirationTime());
        updateData.setGrade(gradeEnum.max(tMember.getGrade()));
        updateById(updateData);
        // 更新等级
        tMember.setGrade(updateData.getGrade());
        refreshUpdateGradeMemberToken(updateData);
        return tMember;

    }


    public void refreshOverTimeMember() {
        List<TMember> list = lambdaQuery().le(TMember::getExpirationTime, new Date()).list();
        if(CollUtil.isEmpty(list)){
            return;
        }
        List<Long> ids = list.stream().map(TMember::getId).collect(Collectors.toList());

        lambdaUpdate()
                .set(TMember::getExpirationTime,null)
                .set(TMember::getActivationTime,null)
                .set(TMember::getGrade,MemberGradeEnum.TOURIST.getType())
                .in(TMember::getId, ids).update();
        Collection<String> keys = redisCache.keys(CacheConstants.LOGIN_TOKEN_KEY + "*");
        for (String key : keys) {
            LoginUser user = redisCache.getCacheObject(key);
            if (!user.getIsClient() && !ids.contains(user.getUserId()) ) {
                continue;
            }
            user.setCGrade(MemberGradeEnum.TOURIST.getType());
            user.setCMemberExpireTime(null);
            tokenService.refreshToken(user);
        }
    }
    public void refreshUpdateGradeMemberToken(TMember member) {
        if(Objects.isNull(member)){
            return;
        }
        Collection<String> keys = redisCache.keys(CacheConstants.LOGIN_TOKEN_KEY + "*");
        for (String key : keys) {
            LoginUser user = redisCache.getCacheObject(key);
            if (!user.getIsClient() && !Objects.equals(member.getId(), user.getUserId()) ) {
                continue;
            }
            user.setCGrade(member.getGrade());
            user.setCMemberExpireTime(member.getExpirationTime());
            tokenService.refreshToken(user);
        }
    }

    /**
     *  刷新正在登陆的会员的等级
     */
    private void refreshLoginMemberGrade(){
        Collection<String> keys = redisCache.keys(CacheConstants.LOGIN_TOKEN_KEY + "*");
        List<SysUserOnline> userOnlineList = new ArrayList<SysUserOnline>();
        for (String key : keys) {
            LoginUser user = redisCache.getCacheObject(key);
            if (user.getIsClient()) {
                continue;
            }
        }
    }
}
